<!doctype html>
<html>
  <head>
    <meta charset=utf-8>
    <title>WebVR IDL test</title>
    <link rel="help" href="https://w3c.github.io/webvr/">

    <script src=/resources/testharness.js></script>
    <script src=/resources/testharnessreport.js></script>
    <script src=/resources/WebIDLParser.js></script>
    <script src=/resources/idlharness.js></script>
<script id="webvr_idl" type=text/plain>
// Archived version of the WebVR spec from
// https://w3c.github.io/webvr/archive/prerelease/1.1/index.html

interface VRDisplay : EventTarget {
  readonly attribute boolean isPresenting;

  /**
   * Dictionary of capabilities describing the VRDisplay.
   */
  [SameObject] readonly attribute VRDisplayCapabilities capabilities;

  /**
   * If this VRDisplay supports room-scale experiences, the optional
   * stage attribute contains details on the room-scale parameters.
   * The stageParameters attribute can not change between null
   * and non-null once the VRDisplay is enumerated; however,
   * the values within VRStageParameters may change after
   * any call to VRDisplay.submitFrame as the user may re-configure
   * their environment at any time.
   */
  readonly attribute VRStageParameters? stageParameters;

  /**
   * Return the current VREyeParameters for the given eye.
   */
  VREyeParameters getEyeParameters(VREye whichEye);

  /**
   * An identifier for this distinct VRDisplay. Used as an
   * association point in the Gamepad API.
   */
  readonly attribute unsigned long displayId;

  /**
   * A display name, a user-readable name identifying it.
   */
  readonly attribute DOMString displayName;

  /**
   * Populates the passed VRFrameData with the information required to render
   * the current frame.
   */
  boolean getFrameData(VRFrameData frameData);

  /**
   * z-depth defining the near plane of the eye view frustum
   * enables mapping of values in the render target depth
   * attachment to scene coordinates. Initially set to 0.01.
   */
  attribute double depthNear;

  /**
   * z-depth defining the far plane of the eye view frustum
   * enables mapping of values in the render target depth
   * attachment to scene coordinates. Initially set to 10000.0.
   */
  attribute double depthFar;

  /**
   * The callback passed to `requestAnimationFrame` will be called
   * any time a new frame should be rendered. When the VRDisplay is
   * presenting the callback will be called at the native refresh
   * rate of the HMD. When not presenting this function acts
   * identically to how window.requestAnimationFrame acts. Content should
   * make no assumptions of frame rate or vsync behavior as the HMD runs
   * asynchronously from other displays and at differing refresh rates.
   */
  long requestAnimationFrame(FrameRequestCallback callback);

  /**
   * Passing the value returned by `requestAnimationFrame` to
   * `cancelAnimationFrame` will unregister the callback.
   */
  void cancelAnimationFrame(long handle);

  /**
   * Begin presenting to the VRDisplay. Must be called in response to a user gesture.
   * Repeat calls while already presenting will update the layers being displayed.
   * If the number of values in the leftBounds/rightBounds arrays is not 0 or 4 for any of the passed layers the promise is rejected
   * If the source of any of the layers is not present (null), the promise is rejected.
   */
  Promise<void> requestPresent(sequence<VRLayerInit> layers);

  /**
   * Stops presenting to the VRDisplay.
   */
  Promise<void> exitPresent();

  /**
   * Get the layers currently being presented.
   */
  sequence<VRLayerInit> getLayers();

  /**
   * The layer provided to the VRDisplay will be captured and presented
   * in the HMD. Calling this function has the same effect on the source
   * canvas as any other operation that uses its source image, and canvases
   * created without preserveDrawingBuffer set to true will be cleared.
   */
  void submitFrame();
};

typedef (HTMLCanvasElement or
         OffscreenCanvas) VRSource;

dictionary VRLayerInit {
  VRSource? source = null;

  sequence<float> leftBounds = [];
  sequence<float> rightBounds = [];
};

interface VRDisplayCapabilities {
  readonly attribute boolean hasPosition;
  readonly attribute boolean hasExternalDisplay;
  readonly attribute boolean canPresent;
  readonly attribute unsigned long maxLayers;
};

enum VREye {
  "left",
  "right"
};

interface VRPose {
  readonly attribute Float32Array? position;
  readonly attribute Float32Array? linearVelocity;
  readonly attribute Float32Array? linearAcceleration;

  readonly attribute Float32Array? orientation;
  readonly attribute Float32Array? angularVelocity;
  readonly attribute Float32Array? angularAcceleration;
};

[Constructor]
interface VRFrameData {
  readonly attribute Float32Array leftProjectionMatrix;
  readonly attribute Float32Array leftViewMatrix;

  readonly attribute Float32Array rightProjectionMatrix;
  readonly attribute Float32Array rightViewMatrix;

  readonly attribute VRPose pose;
};

interface VREyeParameters {
  readonly attribute Float32Array offset;

  readonly attribute unsigned long renderWidth;
  readonly attribute unsigned long renderHeight;
};

interface VRStageParameters {
  readonly attribute Float32Array sittingToStandingTransform;

  readonly attribute float sizeX;
  readonly attribute float sizeZ;
};

partial interface Navigator {
  Promise<sequence<VRDisplay>> getVRDisplays();
  readonly attribute FrozenArray<VRDisplay> activeVRDisplays;
  readonly attribute boolean vrEnabled;
};

enum VRDisplayEventReason {
  "mounted",
  "navigation",
  "requested",
  "unmounted"
};

[Constructor(DOMString type, VRDisplayEventInit eventInitDict)]
interface VRDisplayEvent : Event {
  readonly attribute VRDisplay display;
  readonly attribute VRDisplayEventReason? reason;
};

dictionary VRDisplayEventInit : EventInit {
  required VRDisplay display;
  VRDisplayEventReason reason;
};

partial interface Window {
  attribute EventHandler onvrdisplayconnect;
  attribute EventHandler onvrdisplaydisconnect;
  attribute EventHandler onvrdisplayactivate;
  attribute EventHandler onvrdisplaydeactivate;
  attribute EventHandler onvrdisplayblur;
  attribute EventHandler onvrdisplayfocus;
  attribute EventHandler onvrdisplaypresentchange;
};

partial interface Gamepad {
  readonly attribute unsigned long displayId;
};
</script>
  </head>
  <body>
    <h1 class="instructions">Description</h1>
    <p class="instructions">
      This test verifies that implementations of the WebVR API match its WebIDL definition.
    </p>

    <div id='log'></div>

    <script>
      setup( () => {
        var idl_array = new IdlArray();
        idl_array.add_untested_idls("[Global=Window, Exposed=Window] interface Window {};");
        idl_array.add_untested_idls("interface Navigator {};");
        idl_array.add_untested_idls("interface Event {};");
        idl_array.add_untested_idls("interface EventTarget {};");
        idl_array.add_untested_idls("interface HTMLIFrameElement {};");
        idl_array.add_untested_idls("interface Gamepad {};");

        idl_array.add_untested_idls(`dictionary EventInit {
          boolean bubbles = false;
          boolean cancelable = false;
          boolean composed = false;
        };`);

        idl_array.add_idls(document.getElementById("webvr_idl").textContent);

        idl_array.test();
        done();
      }, {explicit_done: true});
    </script>
  </body>
</html>
